package org.share.comm.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.share.comm.config.PropertiesUtils;
import org.share.comm.os.OSUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 线程池工具类
 * 
 * @author hhm
 *
 */
public class ThreadPool {
	private static final Logger logger = LoggerFactory.getLogger(ThreadPool.class);
	
	/**
	 * 创建线程计数器实例
	 * @return
	 */
	public static ThreadCounter newThreadCounter(){
		return ThreadCounter.newThreadCounter();
	}
	/**
	 * 固定大小连接池
	 * @author hhm
	 *
	 */
	public static class Fixed{
		private static int size = 0 ;
		private static ExecutorService pool = null;
		
		static{
			size = OSUtils.getCPUCount()-1;
			size = PropertiesUtils.getInt("app", "thread_pool_fixed_size", size);
		}
		
		private static synchronized void init(){
			pool = Executors.newFixedThreadPool(size);
			logger.info("create fixed thread pool size : "+size);
		}
		
		public static ExecutorService getThreadPool(){
			if(pool==null || pool.isShutdown()){
				init();
			}
			return pool;
		}	
		
		public static void execute(Runnable r){
			getThreadPool().execute(r);
		}
		
		public static <T> Future<T> submit(Callable<T> task){
			return getThreadPool().submit(task);
		}
		
		public static synchronized void shutdown(){
			pool.shutdown();
		}
		/**
		 * 默认1个小时超时时间自动关闭连接池
		 * @return
		 */
		public static void awaitShutdown(){
			pool.shutdown();
			awaitTermination();
		}
		
		/**
		 * 默认1个小时超时时间自动关闭连接池
		 * @return
		 */
		public static boolean awaitTermination(){
			return awaitTermination(1, TimeUnit.HOURS);
		}
		public static boolean awaitTermination(long timeout, TimeUnit unit){
			try {
				return pool.awaitTermination(30, TimeUnit.MINUTES);
			} catch (InterruptedException e) {
				return false;
			}
		}
		
		public static int getFixedSize(){
			return size;
		}
	}
	
	public static class Cached{
		private static ExecutorService pool = null;
		
		public static ExecutorService getThreadPool(){
			if(pool==null || pool.isShutdown() || pool.isTerminated()){
				pool = Executors.newCachedThreadPool();
			}
			
			return pool;
		}	
		
		public static void execute(Runnable r){
			getThreadPool().execute(r);
		}
		
		public static void shutdown(){
			pool.shutdown();
		}
		
		public static <T> Future<T> submit(Callable<T> task){
			return getThreadPool().submit(task);
		}
	}
	
	public static class Single{
		private static ExecutorService pool = null;
		
		public static ExecutorService getThreadPool(){
			if(pool==null || pool.isShutdown()){
				pool = Executors.newSingleThreadExecutor();
			}
			return pool;
		}	
		
		public static void execute(Runnable r){
			getThreadPool().execute(r);
		}
		
		public static void shutdown(){
			pool.shutdown();
		}
	}
}
